#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <errno.h>
#include <json-c/json.h>
#include "RealtimeWaveform.h"
#include "logInterface.h"
#include "ErrorLog.h"
#include "types.h"
#include "dataBase/errWaveFunction.h"
#include "debug.h"
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>
#include "misc.h"
#include "TableInterface/upper_table_interface.h"


#define ERROR_LOG_QTY (6)

key_t errorMsgKey;  //消息队列的key

struct errorLogData errorlogDataBuff;

struct errorlogFileHead* getErrorlogHeadBuff(){
    return &(errorlogDataBuff.errLogHead);
}

struct errorWaveData* getErrorWaveDataBuff(){
    return &(errorlogDataBuff.errWaveData);
}

uint16_t* getErrorLogPacDataBuff(){

    uint16_t* pPacData = NULL;
    pPacData = (uint16_t*)&(errorlogDataBuff.pacData);
    return pPacData;
}

int errorLogBuffDataFromJson(const char* strErrorLog){

    if(strErrorLog == NULL){
        return -1;
    }

    struct json_object* pacDataObject = NULL;
    struct json_object* errorLogDataObject = json_tokener_parse(strErrorLog);
    struct json_object* pacDataJsonObject = json_object_object_get(errorLogDataObject, "pacData");
    struct json_object* waveDataJsonObject = json_object_object_get(errorLogDataObject, "waveData");
    //获取pac数据
    for(int pacIndex = 0; pacIndex < PAC_DATA_QTY; pacIndex++){
        pacDataObject = json_object_array_get_idx(pacDataJsonObject, pacIndex);
        errorlogDataBuff.pacData[pacIndex] = (uint16_t)json_object_get_uint64(pacDataObject);
    }
    //获取波形数据
    errorGroupWaveDataFromJsonObject(waveDataJsonObject);
    json_object_put(errorLogDataObject);

    return 0;

}

int errorMsgSend(int errorId){

    int errMsg = errorId;

    if(errorId > 256 || errorId < -256)
    {
        return -1;
    }

    if(errorMsgKey < 0){
        printf("错误消息队列初始化失败无法发送消息\n");
        return -1;
    }
    if(msgsnd(errorMsgKey, &errMsg, sizeof(errMsg), 0) == -1){
        printf("错误消息队列发送消息失败\n");
        return -1;
    }

    return 0;
}

//插入一条最新的日志数据
static void error_log_insert_latest_log(int errorId){

    uint16_t pacValue;
    time_t errTime = time(NULL);
    struct json_object* errorLogObject = json_object_new_object(); //错误log数据json对象
    uint32_t curGroupIndex = getCurrentWaveDataGroupIndex();
    //获取参数数据
    struct json_object* upperArrayObject = json_object_new_array_ext(PAC_DATA_QTY);
    for(int idx = 0; idx < PAC_DATA_QTY; idx++){
        UpperTable_Get(idx, &pacValue);
        json_object_array_add(upperArrayObject, json_object_new_uint64(pacValue));
    }
    printf("插入一条pac数据\n");
    json_object_object_add(errorLogObject, "pacData", upperArrayObject);
    //获取40组波形数据
    struct json_object* errorWaveformObject = errorGroupWaveDataToJson(curGroupIndex);
    json_object_object_add(errorLogObject, "waveData", errorWaveformObject);
    insertErrorLog_db(errorId, errTime, curGroupIndex, json_object_to_json_string(errorLogObject));
    json_object_put(errorLogObject);
}

//删除数据库中最老的一条数据，如果数据库中的数据大于6就删除最老的一条，如果没大于6就不用处理
static void error_log_delete_oldest_log(){

    int errQty;

    if(errorLogQty(&errQty) == 0){
        if(errQty > ERROR_LOG_QTY){
            printf("数据量超过6条, 删除最早数据\n");
            deleteErrorLog_db();
        }
        else{
            printf("数据量未超过6条, 不删除\n");
        }
    }
    else{
        printf("数据库数据量查询失败\n");
    }
}

void errorLogUpdate(int errorId){
    error_log_insert_latest_log(errorId); //插入最新的错误log
    error_log_delete_oldest_log();        //删除最老的错误log
}

void Errorlog_Thread(void* pPara){

    Misc_InitThread(__func__);

    int errorMsg, errorId;
    errorMsgKey = msgget(IPC_PRIVATE, IPC_CREAT | 0666);

    if(errorMsgKey == -1){
        printf("错误信息消息队列创建失败\n");
        return;
    }

    while(1){
        msgrcv(errorMsgKey, &errorMsg, sizeof(errorMsg), 0, 0); //阻塞等待消息
        // printf("接收到错误消息%d\n", errorMsg);

        if(errorMsg > 0){
            errorId = errorMsg - 1;
            printf("开始插入一条日志\n");
            logInterfaceLogAdd(LOG_CLASS_SPECIAL, LOG_MAINTYPE_FAULT, (uint16_t)errorId, COM_DATA_TYPE_NONE, NULL);
            printf("插入一条日志\n");
        }
        else{
            errorId = (-1) * errorMsg - 1;
        }

        if(errorMsg > 0){
            errorLogUpdate(errorId);
        }
    }
}


